bitkeeper revision 1.3.1.1 (3df0af24TbrMOYKGDN9rqaVJMewW5Q)
authorakw27@labyrinth.cl.cam.ac.uk <akw27@labyrinth.cl.cam.ac.uk>
Fri, 6 Dec 2002 14:07:32 +0000 (14:07 +0000)
committerakw27@labyrinth.cl.cam.ac.uk <akw27@labyrinth.cl.cam.ac.uk>
Fri, 6 Dec 2002 14:07:32 +0000 (14:07 +0000)
Checkin so that I can pull other updates and see if the net
address fix corrects a nagging bug.  There are a lot of debug messages here and
associated uglies that will be removed in the next checkin.

17 files changed:
.rootkeys
BitKeeper/etc/logging_ok
xen-2.4.16/common/domain.c
xen-2.4.16/common/kernel.c
xen-2.4.16/common/network.c
xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h
xen-2.4.16/include/hypervisor-ifs/network.h
xen-2.4.16/include/xeno/in.h [new file with mode: 0644]
xen-2.4.16/include/xeno/skbuff.h
xen-2.4.16/include/xeno/vif.h
xen-2.4.16/net/dev.c
xen-2.4.16/net/skbuff.c
xenolinux-2.4.16-sparse/arch/xeno/drivers/dom0/vfr.c
xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c
xenolinux-2.4.16-sparse/include/asm-xeno/hypervisor-ifs/hypervisor-if.h
xenolinux-2.4.16-sparse/include/asm-xeno/hypervisor-ifs/network.h
xenolinux-2.4.16-sparse/include/asm-xeno/irq.h

index feb26f56e2f6021ab640af50dc085000d13da64e..7f0a0d435090a5302b5dfb833655b79062ffb016 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 3ddb79c1yHLp08JhgPxIMcZ8DwN9hg xen-2.4.16/include/xeno/if.h
 3ddb79c1RCWOkWPQRzbYVTX_e-E7CA xen-2.4.16/include/xeno/if_ether.h
 3ddb79c2IYah7z7hkzPyOiG8szKkyw xen-2.4.16/include/xeno/if_packet.h
+3df0af1c-QrOEqpPHq4uL3NZzCeJCg xen-2.4.16/include/xeno/in.h
 3ddb79c0GurNF9tDWqQbAwJFH8ugfA xen-2.4.16/include/xeno/init.h
 3ddb79c1Vi5VleJAOKHAlY0G2zAsgw xen-2.4.16/include/xeno/interrupt.h
 3ddb79c2J6EnruiygRhBCgftzMzTeQ xen-2.4.16/include/xeno/ioctl.h
index 05edeace5b85161e076f361bb16ee6276406d56a..0abf014401d2298445162957a405f5cce66b1e22 100644 (file)
@@ -1,2 +1,3 @@
 akw27@boulderdash.cl.cam.ac.uk
+akw27@labyrinth.cl.cam.ac.uk
 smh22@boulderdash.cl.cam.ac.uk
index 784b4e46e61e54cc120f74d5d67d5b69e850ac8b..7dc00d062d895f56834b8f546ff1b94fc00f94d4 100644 (file)
@@ -404,6 +404,7 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params)
     struct pfn_info *page = NULL;
     net_ring_t *net_ring;
     blk_ring_t *blk_ring;
+    net_vif_t *net_vif;
 
     if ( strncmp(__va(mod[0].mod_start), "XenoGues", 8) )
     {
@@ -567,7 +568,8 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params)
 
     /* Add virtual network interfaces and point to them in startinfo. */
     while (params->num_vifs-- > 0) {
-        net_ring = create_net_vif(dom);
+        net_vif = create_net_vif(dom);
+        net_ring = net_vif->net_ring;
         if (!net_ring) panic("no network ring!\n");
     }
     virt_startinfo_address->net_rings = p->net_ring_base;
index 3e860e836b2e98867f589cb2fdaae9830fb9d8c5..110eae665c6c184a757ec6b58c6c4b172de04811 100644 (file)
@@ -174,6 +174,7 @@ void cmain (unsigned long magic, multiboot_info_t *mbi)
     /* Create initial domain 0. */
     dom0_params.num_vifs  = 1;
     dom0_params.memory_kb = opt_dom0_mem;
+    add_default_net_rule(0, opt_ipbase); // add vfr info for dom0
 
     new_dom = do_newdomain();
     if ( new_dom == NULL ) panic("Error creating domain 0\n");
index e64c740f45d78d220cf584be7607f2999fa98fbf..69b42949509f0701fd76cdc6006cf9b6351e1540 100644 (file)
 #include <xeno/init.h>
 #include <xeno/slab.h>
 #include <xeno/spinlock.h>
+#include <xeno/if_ether.h>
+#include <linux/skbuff.h>
+#include <xeno/netdevice.h>
+#include <xeno/in.h>
 
 /* vif globals 
  * sys_vif_list is a lookup table for vifs, used in packet forwarding.
@@ -23,8 +27,11 @@ net_rule_ent_t *net_rule_list;
 kmem_cache_t *net_vif_cache;
 kmem_cache_t *net_rule_cache;
 static rwlock_t net_rule_lock = RW_LOCK_UNLOCKED;
+static rwlock_t sys_vif_lock = RW_LOCK_UNLOCKED;
 
-net_ring_t *create_net_vif(int domain)
+void print_net_rule_list();
+
+net_vif_t *create_net_vif(int domain)
 {
     net_vif_t *new_vif;
     net_ring_t *new_ring;
@@ -39,18 +46,23 @@ net_ring_t *create_net_vif(int domain)
     {
             return NULL;
     }
-    dom_task->net_vif_list[dom_task->num_net_vifs] = new_vif;
     
     new_ring = dom_task->net_ring_base + dom_task->num_net_vifs;
     memset(new_ring, 0, sizeof(net_ring_t));
 
-    dom_task->net_vif_list[dom_task->num_net_vifs]->net_ring = new_ring;
-    skb_queue_head_init(
-                    &dom_task->net_vif_list[dom_task->num_net_vifs]->skb_list);
-    dom_task->net_vif_list[dom_task->num_net_vifs]->id = sys_vif_count++;
-    dom_task->num_net_vifs++;
+    new_vif->net_ring = new_ring;
+    skb_queue_head_init(&new_vif->skb_list);
+    new_vif->domain = domain;
+    
+    write_lock(&sys_vif_lock);
+    new_vif->id = sys_vif_count;
+    sys_vif_list[sys_vif_count++] = new_vif;
+    write_unlock(&sys_vif_lock);
 
-    return new_ring;
+    dom_task->net_vif_list[dom_task->num_net_vifs] = new_vif;
+    dom_task->num_net_vifs++;
+    
+    return new_vif;
 }
 
 /* delete the last vif in the given domain. There doesn't seem to be any reason
@@ -68,9 +80,28 @@ void destroy_net_vif(struct task_struct *p)
     {
         kfree_skb(skb);
     }
+    
+    write_lock(&sys_vif_lock);
+    sys_vif_list[p->net_vif_list[i]->id] = NULL; // system vif list not gc'ed
+    write_unlock(&sys_vif_lock);        
+    
     kmem_cache_free(net_vif_cache, p->net_vif_list[i]);
 }
 
+void print_vif_list()
+{
+    int i;
+    net_vif_t *v;
+
+    printk("Currently, there are %d VIFs.\n", sys_vif_count);
+    for (i=0; i<sys_vif_count; i++)
+    {
+        v = sys_vif_list[i];
+        printk("] VIF Entry %d(%d):\n", i, v->id);
+        printk("   > net_ring*:  %p\n", v->net_ring);
+        printk("   > domain   :  %u\n", v->domain);
+    }
+}
 
 int add_net_rule(net_rule_t *rule)
 {
@@ -94,17 +125,16 @@ int add_net_rule(net_rule_t *rule)
 int delete_net_rule(net_rule_t *rule)
 {
     net_rule_ent_t *ent = net_rule_list, *prev = NULL;
-
-    while ( (ent) && (!(memcmp(rule, &ent->r, sizeof(net_rule_t)))) )
+    while ( (ent) && ((memcmp(rule, &ent->r, sizeof(net_rule_t))) != 0) )
     {
         prev = ent;
         ent = ent->next;
     }
 
-    if (ent)
+    if (ent != NULL)
     {
         write_lock(&net_rule_lock);
-        if (prev)
+        if (prev != NULL)
         {
             prev->next = ent->next;
         }
@@ -115,10 +145,39 @@ int delete_net_rule(net_rule_t *rule)
         kmem_cache_free(net_rule_cache, ent);
         write_unlock(&net_rule_lock);
     }
-
     return 0;
 }
-        
+/* add_default_net_rule.
+ * this is a utility function to route all traffic with the specified
+ * ip address to the specified vif.  It's used to set up domain zero.
+ */
+void add_default_net_rule(int vif_id, u32 ipaddr)
+{
+    net_rule_t new_rule;
+
+    //outbound rule.
+    memset(&new_rule, 0, sizeof(net_rule_t));
+    new_rule.src_addr = ipaddr;
+    new_rule.src_addr_mask = 0xffffffff;
+    new_rule.src_interface = vif_id;
+    new_rule.dst_interface = VIF_PHYSICAL_INTERFACE;
+    new_rule.action = NETWORK_ACTION_ACCEPT;
+    new_rule.proto = NETWORK_PROTO_ANY;
+    add_net_rule(&new_rule);
+
+    //inbound rule;
+    memset(&new_rule, 0, sizeof(net_rule_t));
+    new_rule.dst_addr = ipaddr;
+    new_rule.dst_addr_mask = 0xffffffff;
+    new_rule.src_interface = VIF_PHYSICAL_INTERFACE;
+    new_rule.dst_interface = vif_id;
+    new_rule.action = NETWORK_ACTION_ACCEPT;
+    new_rule.proto = NETWORK_PROTO_ANY;
+    add_net_rule(&new_rule);
+
+}
+
 void print_net_rule(net_rule_t *r)
 {
     printk("===] NET RULE:\n");
@@ -131,8 +190,8 @@ void print_net_rule(net_rule_t *r)
     printk("=] dst_port         : %u\n", r->dst_port);
     printk("=] dst_port_mask    : %u\n", r->dst_port_mask);
     printk("=] dst_proto        : %u\n", r->proto);
-    printk("=] src_interface    : %u\n", r->src_interface);
-    printk("=] dst_interface    : %u\n", r->dst_interface);
+    printk("=] src_interface    : %d\n", r->src_interface);
+    printk("=] dst_interface    : %d\n", r->dst_interface);
     printk("=] action           : %u\n", r->action);
 }
 
@@ -150,6 +209,93 @@ void print_net_rule_list()
     printk("\nTotal of %d rules.\n", count);
 }
 
+/* Apply the rules to this skbuff and return the vif id that it is bound for.
+ * -1 to drop.
+ */
+
+int net_find_rule(u8 nproto, u8 tproto, u32 src_addr, u32 dst_addr, u16 src_port, u16 dst_port, 
+                  int src_vif)
+{
+    net_rule_ent_t *ent;
+    int dest = VIF_DROP;
+    
+    read_lock(&net_rule_lock);
+    
+    ent = net_rule_list;
+    
+    while (ent)
+    {
+        if (    (    (ent->r.src_interface == src_vif) 
+                  || (ent->r.src_interface == VIF_ANY_INTERFACE) )
+
+             && (!((ent->r.src_addr ^ src_addr) & ent->r.src_addr_mask ))
+             && (!((ent->r.dst_addr ^ dst_addr) & ent->r.dst_addr_mask ))
+             && (!((ent->r.src_port ^ src_port) & ent->r.src_port_mask ))
+             && (!((ent->r.dst_port ^ dst_port) & ent->r.dst_port_mask ))
+
+             && (
+                     (ent->r.proto == NETWORK_PROTO_ANY)
+                  || ((ent->r.proto == NETWORK_PROTO_IP)  && (nproto == (u8)ETH_P_IP))
+                  || ((ent->r.proto == NETWORK_PROTO_ARP) && (nproto == (u8)ETH_P_ARP))
+                  || ((ent->r.proto == NETWORK_PROTO_TCP) && (tproto == IPPROTO_TCP))
+                  || ((ent->r.proto == NETWORK_PROTO_UDP) && (tproto == IPPROTO_UDP))
+                )
+           )
+        {
+            break;
+        }
+        ent = ent->next;
+    }
+
+    if (ent) (dest = ent->r.dst_interface);
+    read_unlock(&net_rule_lock);
+    return dest;
+}
+
+int net_get_target_vif(struct sk_buff *skb)
+{
+    int target = VIF_DROP;
+    skb->h.raw = skb->nh.raw = skb->data;
+    if ( skb->len < 2 ) goto drop;
+    switch ( ntohs(skb->mac.ethernet->h_proto) )
+    {
+    case ETH_P_ARP:
+        if ( skb->len < 28 ) goto drop;
+        target = net_find_rule((u8)ETH_P_ARP, 0, ntohl(*(u32 *)(skb->nh.raw + 14)),
+                        ntohl(*(u32 *)(skb->nh.raw + 24)), 0, 0, 
+                        skb->src_vif);
+        break;
+    case ETH_P_IP:
+        if ( skb->len < 20 ) goto drop;
+        skb->h.raw += ((*(unsigned char *)(skb->nh.raw)) & 0x0f) * 4;
+        switch ( *(unsigned char *)(skb->nh.raw + 9) )
+        {
+        case IPPROTO_TCP:
+        case IPPROTO_UDP:
+            target = net_find_rule((u8)ETH_P_IP,  *(u8 *)(skb->nh.raw + 9),
+                    ntohl(*(u32 *)(skb->nh.raw + 12)),
+                    ntohl(*(u32 *)(skb->nh.raw + 16)),
+                    ntohs(*(u16 *)(skb->h.raw)),
+                    ntohs(*(u16 *)(skb->h.raw + 2)), 
+                    skb->src_vif);
+            break;
+        default: // ip-based protocol where we don't have ports.
+            target = net_find_rule((u8)ETH_P_IP,  *(u8 *)(skb->nh.raw + 9),
+                    ntohl(*(u32 *)(skb->nh.raw + 12)),
+                    ntohl(*(u32 *)(skb->nh.raw + 16)),
+                    0,
+                    0, 
+                    skb->src_vif);
+        }
+        break;
+    }
+    skb->dst_vif=target;
+    return target;
+    
+    drop:
+    return VIF_DROP;
+}
+
 /* 
  * This is the hook function to handle guest-invoked traps requesting 
  * changes to the network system.
@@ -199,6 +345,7 @@ long do_network_op(network_op_t *u_network_op)
 void __init net_init (void)
 {
     sys_vif_count = 0;
+    memset(sys_vif_list, 0, sizeof(sys_vif_list));
     net_rule_list = NULL;
     net_vif_cache = kmem_cache_create("net_vif_cache", sizeof(net_vif_t),
                                     0, SLAB_HWCACHE_ALIGN, NULL, NULL);
index 5f57125e6e0f886d7df47286e3bf3b96426ef717..dfa89482c3d5b1bf8cd0407e34935065151eed35 100644 (file)
@@ -165,21 +165,41 @@ static inline int HYPERVISOR_network_op(void *network_op)
     return ret;
 }
 
+/* Event message note:
+ *
+ * Here, as in the interrupts to the guestos, additional network interfaces
+ * are defined.  These definitions server as placeholders for the event bits,
+ * however, in the code these events will allways be referred to as shifted
+ * offsets from the base NET events.
+ */
+
 /* Events that a guest OS may receive from the hypervisor. */
-#define EVENT_NET_TX  0x01 /* packets for transmission. */
-#define EVENT_NET_RX  0x02 /* empty buffers for receive. */
-#define EVENT_TIMER   0x04 /* a timeout has been updated. */
-#define EVENT_DIE     0x08 /* OS is about to be killed. Clean up please! */
-#define EVENT_BLK_TX  0x10 /* packets for transmission. */
-#define EVENT_BLK_RX  0x20 /* empty buffers for receive. */
+#define EVENT_BLK_TX   0x01 /* packets for transmission. */
+#define EVENT_BLK_RX   0x02 /* empty buffers for receive. */
+#define EVENT_TIMER    0x04 /* a timeout has been updated. */
+#define EVENT_DIE      0x08 /* OS is about to be killed. Clean up please! */
+#define EVENT_NET_TX   0x10 /* packets for transmission. */
+#define EVENT_NET_RX   0x20 /* empty buffers for receive. */
+#define EVENT_NET2_TX  0x40 /* packets for transmission. */
+#define EVENT_NET2_RX  0x80 /* empty buffers for receive. */
+
+/* should these macros and the ones below test for range violation? */
+#define EVENT_NET_TX_FOR_VIF(x)    (EVENT_NET_TX << (2 * x))
+#define EVENT_NET_RX_FOR_VIF(x)    (EVENT_NET_RX << (2 * x))
+
 
 /* Bit offsets, as opposed to the above masks. */
-#define _EVENT_NET_TX 0
-#define _EVENT_NET_RX 1
-#define _EVENT_TIMER  2
-#define _EVENT_DIE    3
-#define _EVENT_BLK_TX 4
-#define _EVENT_BLK_RX 5
+#define _EVENT_BLK_TX  0
+#define _EVENT_BLK_RX  1
+#define _EVENT_TIMER   2
+#define _EVENT_DIE     3
+#define _EVENT_NET_TX  4
+#define _EVENT_NET_RX  5
+#define _EVENT_NET2_TX 6
+#define _EVENT_NET2_RX 7
+
+#define _EVENT_NET_TX_FOR_VIF(x)    (_EVENT_NET_TX + (2 * x))
+#define _EVENT_NET_RX_FOR_VIF(x)    (_EVENT_NET_RX + (2 * x))
 
 /*
  * NB. We expect that this struct is smaller than a page.
@@ -191,7 +211,7 @@ typedef struct shared_info_st {
     /*
      * Hypervisor will only signal event delivery via the "callback
      * exception" when this value is non-zero. Hypervisor clears this when
-     * notiying the guest OS -- thsi prevents unbounded reentrancy and
+     * notiying the guest OS -- this prevents unbounded reentrancy and
      * stack overflow (in this way, acts as an interrupt-enable flag).
      */
     unsigned long events_enable;
index 54cb99095a1b6922d17f4dd466de81c6da57c815..a0cfc9fa2ca3f8ba03fcca36090fcbdf757ab4cd 100644 (file)
@@ -52,7 +52,7 @@ typedef struct net_ring_st {
 } net_ring_t;
 
 /* Specify base of per-domain array. Get returned free slot in the array. */
-net_ring_t *create_net_vif(int domain);
+//net_ring_t *create_net_vif(int domain);
 
 /* Packet routing/filtering code follows:
  */
@@ -60,10 +60,11 @@ net_ring_t *create_net_vif(int domain);
 #define NETWORK_ACTION_ACCEPT   0
 #define NETWORK_ACTION_COUNT    1
 
-#define NETWORK_PROTO_IP        0
-#define NETWORK_PROTO_TCP       1
-#define NETWORK_PROTO_UDP       2
-#define NETWORK_PROTO_ARP       3
+#define NETWORK_PROTO_ANY       0
+#define NETWORK_PROTO_IP        1
+#define NETWORK_PROTO_TCP       2
+#define NETWORK_PROTO_UDP       3
+#define NETWORK_PROTO_ARP       4
 
 typedef struct net_rule_st 
 {
@@ -77,8 +78,8 @@ typedef struct net_rule_st
     u16  dst_port_mask;
     u16  proto;
     
-    u16  src_interface;
-    u16 dst_interface;
+    int  src_interface;
+    int  dst_interface;
     u16  action;
 } net_rule_t;
 
diff --git a/xen-2.4.16/include/xeno/in.h b/xen-2.4.16/include/xeno/in.h
new file mode 100644 (file)
index 0000000..1d5f14a
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * INET                An implementation of the TCP/IP protocol suite for the LINUX
+ *             operating system.  INET is implemented using the  BSD Socket
+ *             interface as the means of communication with the user level.
+ *
+ *             Definitions of the Internet Protocol.
+ *
+ * Version:    @(#)in.h        1.0.1   04/21/93
+ *
+ * Authors:    Original taken from the GNU Project <netinet/in.h> file.
+ *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+#ifndef _LINUX_IN_H
+#define _LINUX_IN_H
+
+#include <linux/types.h>
+
+/* Standard well-defined IP protocols.  */
+enum {
+  IPPROTO_IP = 0,              /* Dummy protocol for TCP               */
+  IPPROTO_ICMP = 1,            /* Internet Control Message Protocol    */
+  IPPROTO_IGMP = 2,            /* Internet Group Management Protocol   */
+  IPPROTO_IPIP = 4,            /* IPIP tunnels (older KA9Q tunnels use 94) */
+  IPPROTO_TCP = 6,             /* Transmission Control Protocol        */
+  IPPROTO_EGP = 8,             /* Exterior Gateway Protocol            */
+  IPPROTO_PUP = 12,            /* PUP protocol                         */
+  IPPROTO_UDP = 17,            /* User Datagram Protocol               */
+  IPPROTO_IDP = 22,            /* XNS IDP protocol                     */
+  IPPROTO_RSVP = 46,           /* RSVP protocol                        */
+  IPPROTO_GRE = 47,            /* Cisco GRE tunnels (rfc 1701,1702)    */
+
+  IPPROTO_IPV6  = 41,          /* IPv6-in-IPv4 tunnelling              */
+
+  IPPROTO_PIM    = 103,                /* Protocol Independent Multicast       */
+
+  IPPROTO_ESP = 50,            /* Encapsulation Security Payload protocol */
+  IPPROTO_AH = 51,             /* Authentication Header protocol       */
+  IPPROTO_COMP   = 108,                /* Compression Header protocol */
+
+  IPPROTO_RAW   = 255,         /* Raw IP packets                       */
+  IPPROTO_MAX
+};
+
+
+/* Internet address. */
+struct in_addr {
+       __u32   s_addr;
+};
+
+#define IP_TOS         1
+#define IP_TTL         2
+#define IP_HDRINCL     3
+#define IP_OPTIONS     4
+#define IP_ROUTER_ALERT        5
+#define IP_RECVOPTS    6
+#define IP_RETOPTS     7
+#define IP_PKTINFO     8
+#define IP_PKTOPTIONS  9
+#define IP_MTU_DISCOVER        10
+#define IP_RECVERR     11
+#define IP_RECVTTL     12
+#define        IP_RECVTOS      13
+#define IP_MTU         14
+#define IP_FREEBIND    15
+
+/* BSD compatibility */
+#define IP_RECVRETOPTS IP_RETOPTS
+
+/* IP_MTU_DISCOVER values */
+#define IP_PMTUDISC_DONT               0       /* Never send DF frames */
+#define IP_PMTUDISC_WANT               1       /* Use per route hints  */
+#define IP_PMTUDISC_DO                 2       /* Always DF            */
+
+#define IP_MULTICAST_IF                        32
+#define IP_MULTICAST_TTL               33
+#define IP_MULTICAST_LOOP              34
+#define IP_ADD_MEMBERSHIP              35
+#define IP_DROP_MEMBERSHIP             36
+
+/* These need to appear somewhere around here */
+#define IP_DEFAULT_MULTICAST_TTL        1
+#define IP_DEFAULT_MULTICAST_LOOP       1
+
+/* Request struct for multicast socket ops */
+
+struct ip_mreq 
+{
+       struct in_addr imr_multiaddr;   /* IP multicast address of group */
+       struct in_addr imr_interface;   /* local IP address of interface */
+};
+
+struct ip_mreqn
+{
+       struct in_addr  imr_multiaddr;          /* IP multicast address of group */
+       struct in_addr  imr_address;            /* local IP address of interface */
+       int             imr_ifindex;            /* Interface index */
+};
+
+struct in_pktinfo
+{
+       int             ipi_ifindex;
+       struct in_addr  ipi_spec_dst;
+       struct in_addr  ipi_addr;
+};
+
+/* Structure describing an Internet (IP) socket address. */
+#define __SOCK_SIZE__  16              /* sizeof(struct sockaddr)      */
+struct sockaddr_in {
+  sa_family_t          sin_family;     /* Address family               */
+  unsigned short int   sin_port;       /* Port number                  */
+  struct in_addr       sin_addr;       /* Internet address             */
+
+  /* Pad to size of `struct sockaddr'. */
+  unsigned char                __pad[__SOCK_SIZE__ - sizeof(short int) -
+                       sizeof(unsigned short int) - sizeof(struct in_addr)];
+};
+#define sin_zero       __pad           /* for BSD UNIX comp. -FvK      */
+
+
+/*
+ * Definitions of the bits in an Internet address integer.
+ * On subnets, host and network parts are found according
+ * to the subnet mask, not these masks.
+ */
+#define        IN_CLASSA(a)            ((((long int) (a)) & 0x80000000) == 0)
+#define        IN_CLASSA_NET           0xff000000
+#define        IN_CLASSA_NSHIFT        24
+#define        IN_CLASSA_HOST          (0xffffffff & ~IN_CLASSA_NET)
+#define        IN_CLASSA_MAX           128
+
+#define        IN_CLASSB(a)            ((((long int) (a)) & 0xc0000000) == 0x80000000)
+#define        IN_CLASSB_NET           0xffff0000
+#define        IN_CLASSB_NSHIFT        16
+#define        IN_CLASSB_HOST          (0xffffffff & ~IN_CLASSB_NET)
+#define        IN_CLASSB_MAX           65536
+
+#define        IN_CLASSC(a)            ((((long int) (a)) & 0xe0000000) == 0xc0000000)
+#define        IN_CLASSC_NET           0xffffff00
+#define        IN_CLASSC_NSHIFT        8
+#define        IN_CLASSC_HOST          (0xffffffff & ~IN_CLASSC_NET)
+
+#define        IN_CLASSD(a)            ((((long int) (a)) & 0xf0000000) == 0xe0000000)
+#define        IN_MULTICAST(a)         IN_CLASSD(a)
+#define IN_MULTICAST_NET       0xF0000000
+
+#define        IN_EXPERIMENTAL(a)      ((((long int) (a)) & 0xf0000000) == 0xf0000000)
+#define        IN_BADCLASS(a)          IN_EXPERIMENTAL((a))
+
+/* Address to accept any incoming messages. */
+#define        INADDR_ANY              ((unsigned long int) 0x00000000)
+
+/* Address to send to all hosts. */
+#define        INADDR_BROADCAST        ((unsigned long int) 0xffffffff)
+
+/* Address indicating an error return. */
+#define        INADDR_NONE             ((unsigned long int) 0xffffffff)
+
+/* Network number for local host loopback. */
+#define        IN_LOOPBACKNET          127
+
+/* Address to loopback in software to local host.  */
+#define        INADDR_LOOPBACK         0x7f000001      /* 127.0.0.1   */
+#define        IN_LOOPBACK(a)          ((((long int) (a)) & 0xff000000) == 0x7f000000)
+
+/* Defines for Multicast INADDR */
+#define INADDR_UNSPEC_GROUP    0xe0000000U     /* 224.0.0.0   */
+#define INADDR_ALLHOSTS_GROUP  0xe0000001U     /* 224.0.0.1   */
+#define INADDR_ALLRTRS_GROUP    0xe0000002U    /* 224.0.0.2 */
+#define INADDR_MAX_LOCAL_GROUP  0xe00000ffU    /* 224.0.0.255 */
+
+
+/* <asm/byteorder.h> contains the htonl type stuff.. */
+#include <asm/byteorder.h> 
+
+#ifdef __KERNEL__
+/* Some random defines to make it easier in the kernel.. */
+#define LOOPBACK(x)    (((x) & htonl(0xff000000)) == htonl(0x7f000000))
+#define MULTICAST(x)   (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
+#define BADCLASS(x)    (((x) & htonl(0xf0000000)) == htonl(0xf0000000))
+#define ZERONET(x)     (((x) & htonl(0xff000000)) == htonl(0x00000000))
+#define LOCAL_MCAST(x) (((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
+
+#endif
+
+#endif /* _LINUX_IN_H */
index 4a540d8e0bccee3822eb9fd3779fa60fe9613070..f9c38c12bf8eda25de507863851cd0484ee22b60 100644 (file)
 #include <linux/mm.h>
 //#include <linux/highmem.h>
 
+// vif special values.
+#define VIF_PHYSICAL_INTERFACE  -1
+#define VIF_UNKNOWN_INTERFACE   -2
+#define VIF_DROP                -3
+#define VIF_ANY_INTERFACE       -4
+
 #define HAVE_ALLOC_SKB         /* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB     /* Ditto 8)                */
 #define SLAB_SKB               /* Slabified skbuffs       */
@@ -196,6 +202,12 @@ struct sk_buff {
        unsigned char   *end;                   /* End pointer                                  */
 
        void            (*destructor)(struct sk_buff *);        /* Destruct function            */
+
+        int src_vif;                            /* vif we came from */
+        int dst_vif;                            /* vif we are bound for */
+
+                
+        
 #ifdef CONFIG_NETFILTER
        /* Can be used for communication between hooks. */
         unsigned long  nfmark;
index 6c1a1807a553c07b1f18862776e6056c16590144..2a2612ec7021ce0735321a9d0cba9c07667c1672 100644 (file)
@@ -20,6 +20,7 @@ typedef struct net_vif_st {
     net_ring_t  *net_ring;
     int          id;
     struct sk_buff_head skb_list;
+    unsigned int domain;
     // rules table goes here in next revision.
 } net_vif_t;
 
@@ -32,6 +33,8 @@ extern int sys_vif_count;
 extern net_vif_t *sys_vif_list[];
 
 /* vif prototypes */
-net_ring_t *create_net_vif(int domain);
+net_vif_t *create_net_vif(int domain);
 void destroy_net_vif(struct task_struct *p);
-
+void add_default_net_rule(int vif_id, u32 ipaddr);
+int net_get_target_vif(struct sk_buff *skb);
+void add_default_net_rule(int vif_id, u32 ipaddr);
index dd376df98d5e279a4913e89d809aba5627e0e129..cd3a4e38d3421a2069006c38a0d880c37249a365 100644 (file)
@@ -687,7 +687,7 @@ int netif_rx(struct sk_buff *skb)
         unsigned long cpu_mask;
 #endif
         struct task_struct *p;
-        unsigned int dest_dom;
+//        unsigned int dest_dom;
        int this_cpu = smp_processor_id();
        struct softnet_data *queue;
        unsigned long flags;
@@ -703,7 +703,7 @@ int netif_rx(struct sk_buff *skb)
        local_irq_save(flags);
         
        netdev_rx_stat[this_cpu].total++;
-
+/*
         skb->h.raw = skb->nh.raw = skb->data;
         
         if ( skb->len < 2 ) goto drop;
@@ -741,8 +741,36 @@ int netif_rx(struct sk_buff *skb)
         while ( (p = p->next_task) != &idle0_task );
         read_unlock(&tasklist_lock);
         goto drop;
+*/
+        if (skb->src_vif == VIF_UNKNOWN_INTERFACE)
+            skb->src_vif = VIF_PHYSICAL_INTERFACE;
+
+        if (skb->dst_vif == VIF_UNKNOWN_INTERFACE)
+            net_get_target_vif(skb);
+if (skb->dst_vif > 1)
+printk("netifrx got packet bound for system vif %d.\n", skb->dst_vif);
+        if (sys_vif_list[skb->dst_vif] == NULL)
+        {
+            // the target vif does not exist.
+            goto drop;
+        }
 
- found:
+        if ( skb->dst_vif >= VIF_PHYSICAL_INTERFACE )
+        {
+            read_lock(&tasklist_lock);
+            p = &idle0_task;
+            do {
+                if ( p->domain != sys_vif_list[skb->dst_vif]->domain ) continue;
+                skb_queue_tail(&sys_vif_list[skb->dst_vif]->skb_list, skb);
+                cpu_mask = mark_hyp_event(p, _HYP_EVENT_NET_RX);
+                read_unlock(&tasklist_lock);
+                goto found;
+            }
+            while ( (p = p->next_task) != &idle0_task );
+            read_unlock(&tasklist_lock); 
+            goto drop;
+        }
+// found:
 #if 0
         __skb_queue_tail(&queue->input_pkt_queue,skb);
         /* Runs from irqs or BH's, no need to wake BH */
@@ -750,7 +778,7 @@ int netif_rx(struct sk_buff *skb)
         local_irq_restore(flags);
         get_sample_stats(this_cpu);
         return softnet_data[this_cpu].cng_level;
-#else
+//#else
         hyp_event_notify(cpu_mask);
         local_irq_restore(flags);
         return 0;
@@ -762,6 +790,11 @@ drop:
 
        kfree_skb(skb);
        return NET_RX_DROP;
+
+found:
+        hyp_event_notify(cpu_mask);
+        local_irq_restore(flags);
+        return 0;
 }
 
 /* Deliver skb to an old protocol, which is not threaded well
@@ -890,6 +923,18 @@ void flush_rx_queue(void)
     unsigned int i, nvif;
     rx_entry_t rx;
 
+    /* I have changed this to batch flush all vifs for a guest
+     * at once, whenever this is called.  Since the guest is about to be
+     * scheduled and issued an RX interrupt for one nic, it might as well
+     * receive all pending traffic  although it will still only get
+     * interrupts about rings that pass the event marker.  
+     *
+     * If this doesn't make sense, _HYP_EVENT_NET_RX can be modified to
+     * represent individual interrups as _EVENT_NET_RX and the outer for
+     * loop can be replaced with a translation to the specific NET 
+     * interrupt to serve. --akw
+     */
+    
     clear_bit(_HYP_EVENT_NET_RX, &current->hyp_events);
 
     for (nvif = 0; nvif < current->num_net_vifs; nvif++)
@@ -898,15 +943,25 @@ void flush_rx_queue(void)
         while ( (skb = skb_dequeue(&current->net_vif_list[nvif]->skb_list)) 
                         != NULL )
         {
+if (nvif > 0)
+printk("flushrxqueue on vif %d (sys: %d) (pkt_type=%d)\n", nvif, current->net_vif_list[nvif]->id, skb->pkt_type);
             /*
              * Write the virtual MAC address into the destination field
              * of the ethernet packet. Furthermore, do the same for ARP
              * reply packets. This is easy because the virtual MAC address
              * is always 00-00-00-00-00-00.
+             *
+             * Actually, the MAC address is now all zeros, except for the
+             * first sixteen bits, which are the per-host vif id.
+             * (so eth0 should be 00-00-..., eth1 is 01-00-...)
              */
             memset(skb->mac.ethernet->h_dest, 0, ETH_ALEN);
+            *(unsigned int *)(skb->mac.ethernet->h_dest) = nvif;
             if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP )
+            {
                 memset(skb->nh.raw + 18, 0, ETH_ALEN);
+                *(unsigned int *)(skb->nh.raw + 18) = nvif;
+            }
 
             i = net_ring->rx_cons;
             if ( i != net_ring->rx_prod )
@@ -920,7 +975,7 @@ void flush_rx_queue(void)
                 }
                 net_ring->rx_cons = (i+1) & (RX_RING_SIZE-1);
                 if ( net_ring->rx_cons == net_ring->rx_event )
-                    set_bit(_EVENT_NET_RX, &s->events);
+                    set_bit(_EVENT_NET_RX_FOR_VIF(nvif), &s->events);
             }
             kfree_skb(skb);
         }
@@ -1912,20 +1967,24 @@ long do_net_update(void)
 {
     shared_info_t *shared = current->shared_info;    
     net_ring_t *net_ring = current->net_ring_base;
+    net_vif_t *current_vif;
     unsigned int i, j;
     struct sk_buff *skb;
     tx_entry_t tx;
 
     for ( j = 0; j < current->num_net_vifs; j++)
     {
-        net_ring = current->net_vif_list[j]->net_ring;
+        current_vif = current->net_vif_list[j];
+        net_ring = current_vif->net_ring;
         for ( i = net_ring->tx_cons; i != net_ring->tx_prod; i = TX_RING_INC(i) )
         {
+if (j > 0)
+printk("net_update called with packet on vif %d system: %d)\n", j, current_vif->id);
             if ( copy_from_user(&tx, net_ring->tx_ring+i, sizeof(tx)) )
                 continue;
 
             if ( TX_RING_INC(i) == net_ring->tx_event )
-                set_bit(_EVENT_NET_TX, &shared->events);
+                set_bit(_EVENT_NET_TX_FOR_VIF(j), &shared->events);
 
             skb = alloc_skb(tx.size, GFP_KERNEL);
             if ( skb == NULL ) continue;
@@ -1965,17 +2024,44 @@ long do_net_update(void)
             {
                 skb_get(skb); /* get a reference for non-local delivery */
                 skb->protocol = eth_type_trans(skb, skb->dev);
+                skb->src_vif = current_vif->id; 
+                net_get_target_vif(skb);
+                if ( skb->dst_vif > VIF_PHYSICAL_INTERFACE )
+                {
+if (j > 0)
+    printk("Sent to netif_rx.\n");
+                    if (netif_rx(skb) == 0)
+                        /* Give up non-local reference. Packet delivered locally. */
+                        kfree_skb(skb);
+                }
+                else if ( skb->dst_vif == VIF_PHYSICAL_INTERFACE )
+                {
+if (j > 0)
+    printk("Sent to physical device.\n");
+
+                        skb_push(skb, skb->dev->hard_header_len);
+                        dev_queue_xmit(skb);
+                } 
+                else
+                {
+if (j > 0)
+    printk("dropped.\n");
+                    kfree_skb(skb);
+                }
+
+                /*
+                skb_get(skb); 
+                skb->protocol = eth_type_trans(skb, skb->dev);
                 if ( netif_rx(skb) == 0 )
                 {
-                    /* Give up non-local reference. Packet delivered locally. */
                     kfree_skb(skb);
                 }
                 else
                 {
-                    /* Pass the non-local reference to the net device. */
                     skb_push(skb, skb->dev->hard_header_len);
                     dev_queue_xmit(skb);
                 }
+                */
             }
         }
         net_ring->tx_cons = i;
index 7ed619c5ee2ff94d4a29c84bf628899a98012735..07896fda7894e845e568f289e02d7997281045b3 100644 (file)
@@ -211,6 +211,8 @@ struct sk_buff *alloc_skb(unsigned int size,int gfp_mask)
        skb->len = 0;
        skb->cloned = 0;
        skb->data_len = 0;
+        skb->src_vif = VIF_UNKNOWN_INTERFACE;
+        skb->dst_vif = VIF_UNKNOWN_INTERFACE;
 
        atomic_set(&skb->users, 1); 
        atomic_set(&(skb_shinfo(skb)->dataref), 1);
index 3f22282cee2d66d7ecee56429653405b7eb4d5e5..d6f6616262a49c26504c663b3b887e56d02aad81 100644 (file)
@@ -23,6 +23,7 @@ static unsigned char readbuf[1024];
 /* Helpers, implemented at the bottom. */
 u32 getipaddr(const char *buff, unsigned int len);
 u16 antous(const char *buff, int len);
+int anton(const char *buff, int len);
 
 static int vfr_read_proc(char *page, char **start, off_t off,
                                           int count, int *eof, void *data)
@@ -136,53 +137,55 @@ static int vfr_write_proc(struct file *file, const char *buffer,
 
     if (strncmp(&buffer[fs], "srcaddr", fl) == 0) 
     {  
-      op.u.net_rule.src_addr = getipaddr(&buffer[ts], tl-1);
+      op.u.net_rule.src_addr = getipaddr(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "dstaddr", fl) == 0)
     {    
-      op.u.net_rule.dst_addr = getipaddr(&buffer[ts], tl-1);
+      op.u.net_rule.dst_addr = getipaddr(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "srcaddrmask", fl) == 0) 
     {
-      op.u.net_rule.src_addr_mask = getipaddr(&buffer[ts], tl-1);
+      op.u.net_rule.src_addr_mask = getipaddr(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "dstaddrmask", fl) == 0)
     {
-      op.u.net_rule.dst_addr_mask = getipaddr(&buffer[ts], tl-1);
+      op.u.net_rule.dst_addr_mask = getipaddr(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "srcport", fl) == 0)
     {
-      op.u.net_rule.src_port = antous(&buffer[ts], tl-1);
+      op.u.net_rule.src_port = antous(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "dstport", fl) == 0)
     {
-      op.u.net_rule.dst_port = antous(&buffer[ts], tl-1);
+      op.u.net_rule.dst_port = antous(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "srcportmask", fl) == 0)
     {
-      op.u.net_rule.src_port_mask = antous(&buffer[ts], tl-1);
+      op.u.net_rule.src_port_mask = antous(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "dstportmask", fl) == 0)
     {
-      op.u.net_rule.dst_port_mask = antous(&buffer[ts], tl-1);
+      op.u.net_rule.dst_port_mask = antous(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "srcint", fl) == 0)
     {
-      op.u.net_rule.src_interface = antous(&buffer[ts], tl-1);
+      op.u.net_rule.src_interface = anton(&buffer[ts], tl);
     }
     else if (strncmp(&buffer[fs], "dstint", fl) == 0)
     {
-      op.u.net_rule.dst_interface = antous(&buffer[ts], tl-1);
+      op.u.net_rule.dst_interface = anton(&buffer[ts], tl);
     }
     else if ( (strncmp(&buffer[fs], "proto", fl) == 0))
     {
-      if (strncmp(&buffer[ts], "ip", tl))
+      if (strncmp(&buffer[ts], "any", tl) == 0)
+          op.u.net_rule.proto = NETWORK_PROTO_ANY;
+      if (strncmp(&buffer[ts], "ip", tl) == 0)
          op.u.net_rule.proto = NETWORK_PROTO_IP;
-      if (strncmp(&buffer[ts], "tcp", tl))
+      if (strncmp(&buffer[ts], "tcp", tl) == 0) 
          op.u.net_rule.proto = NETWORK_PROTO_TCP;
-      if (strncmp(&buffer[ts], "udp", tl))
+      if (strncmp(&buffer[ts], "udp", tl) == 0)
          op.u.net_rule.proto = NETWORK_PROTO_UDP;
-      if (strncmp(&buffer[ts], "arp", tl))
+      if (strncmp(&buffer[ts], "arp", tl) == 0)
          op.u.net_rule.proto = NETWORK_PROTO_ARP;
       
     }
@@ -225,9 +228,31 @@ module_exit(cleanup_module);
 
 /* Helper functions start here: */
 
+int anton(const char *buff, int len)
+{
+    int ret;
+    char c;
+    int sign = 1;
+    
+    ret = 0;
+
+    if (len == 0) return 0;
+    if (*buff == '-') { sign = -1; buff++; len--; }
+
+    while ( (len) && ((c = *buff) >= '0') && (c <= '9') )
+    {
+        ret *= 10;
+        ret += c - '0';
+        buff++; len--;
+    }
+
+    ret *= sign;
+    return ret;
+}
+    
 u16 antous(const char *buff, int len)
 {
-  int ret;
+  u16 ret;
   char c;
 
   ret = 0;
index 7e1825f87344cb58ca39c2db391cd29c1509ba6a..c4b4a9cc9d70fb4436b57c54dd18fc4d75413b4b 100644 (file)
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/ip.h> //remove this.
 
 #include <net/sock.h>
 
 #define NET_TX_IRQ _EVENT_NET_TX
 #define NET_RX_IRQ _EVENT_NET_RX
 
+#define NET_TX_IRQ_FOR_VIF(x) _EVENT_NET_TX_FOR_VIF(x)
+#define NET_RX_IRQ_FOR_VIF(x) _EVENT_NET_RX_FOR_VIF(x)
+
 #define TX_MAX_ENTRIES (TX_RING_SIZE - 2)
 #define RX_MAX_ENTRIES (RX_RING_SIZE - 2)
 
@@ -62,6 +66,7 @@ struct net_private
     unsigned int rx_idx, tx_idx, tx_full;
     net_ring_t *net_ring;
     spinlock_t tx_lock;
+    unsigned int id;
 };
 
  
@@ -69,7 +74,15 @@ static int network_open(struct net_device *dev)
 {
     struct net_private *np = dev->priv;
     int error;
-
+    char *rxlabel, *txlabel;
+
+    // This is inevitably not the right way to allocate a couple of static strings.
+    rxlabel = kmalloc(sizeof("net-rx- "), GFP_KERNEL);
+    txlabel = kmalloc(sizeof("net-tx- "), GFP_KERNEL);
+    if ((rxlabel == NULL) || (txlabel == NULL)) goto fail;
+    sprintf(rxlabel, "net-rx-%d", np->id);
+    sprintf(txlabel, "net-tx-%d", np->id);
+    
     np->rx_idx = np->tx_idx = np->tx_full = 0;
 
     memset(&np->stats, 0, sizeof(np->stats));
@@ -101,7 +114,8 @@ static int network_open(struct net_device *dev)
 
     network_alloc_rx_buffers(dev);
 
-    error = request_irq(NET_RX_IRQ, network_rx_int, 0, "net-rx", dev);
+    error = request_irq(NET_RX_IRQ_FOR_VIF(np->id), network_rx_int, 0, 
+                    rxlabel, dev);
     if ( error )
     {
         printk(KERN_WARNING "%s: Could not allocate receive interrupt\n",
@@ -109,12 +123,13 @@ static int network_open(struct net_device *dev)
         goto fail;
     }
 
-    error = request_irq(NET_TX_IRQ, network_tx_int, 0, "net-tx", dev);
+    error = request_irq(NET_TX_IRQ_FOR_VIF(np->id), network_tx_int, 0, 
+                    txlabel, dev);
     if ( error )
     {
         printk(KERN_WARNING "%s: Could not allocate transmit interrupt\n",
                dev->name);
-        free_irq(NET_RX_IRQ, dev);
+        free_irq(NET_RX_IRQ_FOR_VIF(np->id), dev);
         goto fail;
     }
 
@@ -127,6 +142,8 @@ static int network_open(struct net_device *dev)
     return 0;
 
  fail:
+    if ( rxlabel ) kfree(rxlabel);
+    if ( txlabel ) kfree(txlabel);
     if ( np->net_ring->rx_ring ) kfree(np->net_ring->rx_ring);
     if ( np->net_ring->tx_ring ) kfree(np->net_ring->tx_ring);
     if ( np->rx_skb_ring ) kfree(np->rx_skb_ring);
@@ -208,7 +225,12 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     unsigned int i;
     struct net_private *np = (struct net_private *)dev->priv;
-
+    
+if ((np->id > 0) || ((skb->len > 20) 
+                && (skb->nh.iph != NULL) 
+                && (skb->nh.iph->protocol == 1)))
+    printk(KERN_WARNING "TX on vif %d (dev:%p)\n", np->id, dev);
+    
     if ( np->tx_full )
     {
         printk(KERN_WARNING "%s: full queue wasn't stopped!\n", dev->name);
@@ -265,8 +287,17 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
         skb->protocol = eth_type_trans(skb, dev);
         np->stats.rx_packets++;
         np->stats.rx_bytes += np->net_ring->rx_ring[i].size;
+
+if (((skb->len > 20)
+    && ((*(unsigned char *)(skb->data + 9) == 1) || (np->id > 0)) ))
+    printk(KERN_WARNING "RX on vif %d (dev:%p)\n", np->id, dev);
+if ((skb != NULL) && (skb->data != NULL) && (skb->len > 20) && ntohl(*(unsigned long *)(skb->data + 16)) == 167903489)
+    printk(KERN_WARNING "RX INT (driver): pkt_type is %d.!", skb->pkt_type);
+
         netif_rx(skb);
         dev->last_rx = jiffies;
+                
+
     }
 
     np->rx_idx = i;
@@ -275,7 +306,10 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
     
     /* Deal with hypervisor racing our resetting of rx_event. */
     smp_mb();
-    if ( np->net_ring->rx_cons != i ) goto again;
+    if ( np->net_ring->rx_cons != i ) { 
+//printk("redoing network rx...\n"); 
+                goto again;
+        }
 }
 
 
@@ -286,13 +320,13 @@ static void network_tx_int(int irq, void *dev_id, struct pt_regs *ptregs)
 }
 
 
-static int network_close(struct net_device *dev)
+int network_close(struct net_device *dev)
 {
     struct net_private *np = dev->priv;
 
     netif_stop_queue(dev);
-    free_irq(NET_RX_IRQ, dev);
-    free_irq(NET_TX_IRQ, dev);
+    free_irq(NET_RX_IRQ_FOR_VIF(np->id), dev);
+    free_irq(NET_TX_IRQ_FOR_VIF(np->id), dev);
     network_free_rx_buffers(dev);
     kfree(np->net_ring->rx_ring);
     kfree(np->net_ring->tx_ring);
@@ -310,7 +344,7 @@ static struct net_device_stats *network_get_stats(struct net_device *dev)
 }
 
 
-static int __init init_module(void)
+int __init init_module(void)
 {
     int i, err;
     struct net_device *dev;
@@ -336,6 +370,9 @@ static int __init init_module(void)
         dev->stop            = network_close;
         dev->get_stats       = network_get_stats;
 
+        memset(dev->dev_addr, 0, ETH_ALEN);
+        *(unsigned int *)(dev->dev_addr) = i;
+
         if ( (err = register_netdev(dev)) != 0 )
         {
             kfree(dev);
@@ -343,7 +380,9 @@ static int __init init_module(void)
         }
 
         np->dev = dev;
+        np->id = i;
         list_add(&np->list, &dev_list);
+printk(KERN_WARNING "Added VIF, ifindex is %d.\n", dev->ifindex);
     }
 
     return 0;
index 6a362d36356440ab2c137b216c42bac6931a1733..3d6c56b59fb8dbc622665cc094cbad7fa4c880ef 100644 (file)
@@ -165,21 +165,41 @@ static inline int HYPERVISOR_network_op(void *network_op)
     return ret;
 }
 
+/* Event message note:
+ *
+ * Here, as in the interrupts to the guestos, additional network interfaces
+ * are defined.  These definitions server as placeholders for the event bits,
+ * however, in the code these events will allways be referred to as shifted
+ * offsets from the base NET events.
+ */
+
 /* Events that a guest OS may receive from the hypervisor. */
-#define EVENT_NET_TX  0x01 /* packets for transmission. */
-#define EVENT_NET_RX  0x02 /* empty buffers for receive. */
-#define EVENT_TIMER   0x04 /* a timeout has been updated. */
-#define EVENT_DIE     0x08 /* OS is about to be killed. Clean up please! */
-#define EVENT_BLK_TX  0x10 /* packets for transmission. */
-#define EVENT_BLK_RX  0x20 /* empty buffers for receive. */
+#define EVENT_BLK_TX   0x01 /* packets for transmission. */
+#define EVENT_BLK_RX   0x02 /* empty buffers for receive. */
+#define EVENT_TIMER    0x04 /* a timeout has been updated. */
+#define EVENT_DIE      0x08 /* OS is about to be killed. Clean up please! */
+#define EVENT_NET_TX   0x10 /* packets for transmission. */
+#define EVENT_NET_RX   0x20 /* empty buffers for receive. */
+#define EVENT_NET2_TX  0x40 /* packets for transmission. */
+#define EVENT_NET2_RX  0x80 /* empty buffers for receive. */
+
+/* should these macros and the ones below test for range violation? */
+#define EVENT_NET_TX_FOR_VIF(x)    (EVENT_NET_TX << (2 * x))
+#define EVENT_NET_RX_FOR_VIF(x)    (EVENT_NET_RX << (2 * x))
+
 
 /* Bit offsets, as opposed to the above masks. */
-#define _EVENT_NET_TX 0
-#define _EVENT_NET_RX 1
-#define _EVENT_TIMER  2
-#define _EVENT_DIE    3
-#define _EVENT_BLK_TX 4
-#define _EVENT_BLK_RX 5
+#define _EVENT_BLK_TX  0
+#define _EVENT_BLK_RX  1
+#define _EVENT_TIMER   2
+#define _EVENT_DIE     3
+#define _EVENT_NET_TX  4
+#define _EVENT_NET_RX  5
+#define _EVENT_NET2_TX 6
+#define _EVENT_NET2_RX 7
+
+#define _EVENT_NET_TX_FOR_VIF(x)    (_EVENT_NET_TX + (2 * x))
+#define _EVENT_NET_RX_FOR_VIF(x)    (_EVENT_NET_RX + (2 * x))
 
 /*
  * NB. We expect that this struct is smaller than a page.
@@ -263,6 +283,7 @@ typedef struct start_info_st {
     int num_net_rings;
     blk_ring_t *blk_ring;         /* block io communication rings */
     unsigned char cmd_line[1];    /* variable-length */
+    unsigned long frame_table;    /* mapping of the frame_table for dom0 */
 } start_info_t;
 
 /* For use in guest OSes. */
index 54cb99095a1b6922d17f4dd466de81c6da57c815..a0cfc9fa2ca3f8ba03fcca36090fcbdf757ab4cd 100644 (file)
@@ -52,7 +52,7 @@ typedef struct net_ring_st {
 } net_ring_t;
 
 /* Specify base of per-domain array. Get returned free slot in the array. */
-net_ring_t *create_net_vif(int domain);
+//net_ring_t *create_net_vif(int domain);
 
 /* Packet routing/filtering code follows:
  */
@@ -60,10 +60,11 @@ net_ring_t *create_net_vif(int domain);
 #define NETWORK_ACTION_ACCEPT   0
 #define NETWORK_ACTION_COUNT    1
 
-#define NETWORK_PROTO_IP        0
-#define NETWORK_PROTO_TCP       1
-#define NETWORK_PROTO_UDP       2
-#define NETWORK_PROTO_ARP       3
+#define NETWORK_PROTO_ANY       0
+#define NETWORK_PROTO_IP        1
+#define NETWORK_PROTO_TCP       2
+#define NETWORK_PROTO_UDP       3
+#define NETWORK_PROTO_ARP       4
 
 typedef struct net_rule_st 
 {
@@ -77,8 +78,8 @@ typedef struct net_rule_st
     u16  dst_port_mask;
     u16  proto;
     
-    u16  src_interface;
-    u16 dst_interface;
+    int  src_interface;
+    int  dst_interface;
     u16  action;
 } net_rule_t;
 
index f5f65b8b8260e32057f3ddd51209f52f38e1636d..619353e6968a6f20377d78011219b9cb19bc51a4 100644 (file)
@@ -16,6 +16,8 @@
 
 #define NET_TX_IRQ  _EVENT_NET_TX
 #define NET_RX_IRQ  _EVENT_NET_RX
+#define NET2_TX_IRQ  _EVENT_NET2_TX
+#define NET2_RX_IRQ  _EVENT_NET2_RX
 #define TIMER_IRQ   _EVENT_TIMER
 
 #define NR_IRQS (sizeof(HYPERVISOR_shared_info->events) * 8)